package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.ApArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jack
 * @data 2023 14:31
 */
@Service
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {
    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private CacheService cacheService;

    @Override
    public void hotArticle() {
        //1. 查询前5天的文章
        //先计算得到一个5天前的此刻
        Date fiveDatesAgo = new Date(System.currentTimeMillis() - (1000L * 60 * 60 * 24 * 5));
        List<ApArticle> allArticleList = apArticleMapper.selectList(Wrappers.<ApArticle>lambdaQuery().ge(ApArticle::getPublishTime,fiveDatesAgo));

        //2. 计算文章分值
        List<ApArticleVo> voList = computeScore(allArticleList);
        if (voList != null && voList.size() > 0){
            //3.1 计算每个频道下的热点文章，取前30名，存入redis作为该频道下的热点文章
            //先拿到所有文章对应的频道
            List<Integer> channels = voList.stream().map(ApArticleVo::getChannelId).distinct().collect(Collectors.toList());
            for (Integer channelId : channels) {
                //得到当前频道下的所有文章
                List<ApArticleVo> articleInSameChannel = voList.stream().filter(apArticleVo -> apArticleVo.getChannelId().equals(channelId)).collect(Collectors.toList());
                //对文章进行按分降序排列
                Collections.sort(articleInSameChannel, new Comparator<ApArticleVo>() {
                    @Override
                    public int compare(ApArticleVo o1, ApArticleVo o2) {
                        return o2.getScore() - o1.getScore();
                    }
                });
                //取前30条分值较高的文章放到redis
                if (articleInSameChannel.size() > 30) {
                    articleInSameChannel = articleInSameChannel.stream().limit(30).collect(Collectors.toList());
                }
                //将处理好的数据存入redis
                cacheService.set("hot_article_"+channelId, JSON.toJSONString(articleInSameChannel));
            }



        }


        //3.2 计算推荐频道下的热点文章，取总的前30名，存入redis作为该频道下的热点文章
        //对文章进行按分降序排列
        Collections.sort(voList, new Comparator<ApArticleVo>() {
            @Override
            public int compare(ApArticleVo o1, ApArticleVo o2) {
                return o2.getScore() - o1.getScore();
            }
        });

        //取前30条分值较高的文章放到redis
        if (voList.size() > 30) {
            voList = voList.stream().limit(30).collect(Collectors.toList());
        }

        //将处理好的数据存入redis
        cacheService.set("hot_article___all__", JSON.toJSONString(voList));

    }

    //给文章算分
    private List<ApArticleVo> computeScore(List<ApArticle> allArticleList) {
        if (allArticleList != null && allArticleList.size() > 0){
            List<ApArticleVo> resList = new ArrayList<>();

            for (int i = 0; i < allArticleList.size(); i++) {
                ApArticle article = allArticleList.get(i);

                //给文章算分
                int score = 0;
                //阅读权重 ： 1
                if (article.getViews() != null && article.getViews() > 0){
                    score += (article.getViews() * 1);
                }
                //点赞权重 ： 3
                if (article.getLikes() != null && article.getLikes() > 0){
                    score += (article.getLikes() * 3);
                }
                //评论权重 ： 5
                if (article.getComment() != null && article.getComment() > 0){
                    score += (article.getComment() * 5);
                }
                //收藏权重 ： 8
                if (article.getCollection() != null && article.getCollection() > 0){
                    score += (article.getCollection() * 8);
                }

                ApArticleVo apArticleVo = new ApArticleVo();
                BeanUtils.copyProperties(article,apArticleVo);
                apArticleVo.setScore(score);

                resList.add(apArticleVo);
            }

            return resList;
        }

        return null;

    }
}
